{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from langchain_core.tools import tool\n",
    "from ChatGLM_new import tongyi_llm\n",
    "from langchain_core.utils.function_calling import convert_to_openai_tool"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "@tool\n",
    "def multiply(x: float, y: float) -> float:\n",
    "    \"\"\"Multiply two numbers together.\"\"\"\n",
    "    return x * y\n",
    "\n",
    "\n",
    "@tool\n",
    "def add(x: int, y: int) -> int:\n",
    "    \"Add two numbers.\"\n",
    "    return x + y\n",
    "\n",
    "\n",
    "@tool\n",
    "def count_emails(last_n_days: int) -> int:\n",
    "    \"\"\"Multiply two integers together.\"\"\"\n",
    "    return last_n_days * 2\n",
    "\n",
    "\n",
    "@tool\n",
    "def send_email(message: str, recipient: str) -> str:\n",
    "    \"Add two integers.\"\n",
    "    return f\"Successfully sent email to {recipient}.\"\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [],
   "source": [
    "tools = [multiply, add, count_emails, send_email]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[StructuredTool(name='multiply', description='Multiply two numbers together.', args_schema=<class 'pydantic.v1.main.multiplySchema'>, func=<function multiply at 0x000002725DBF67A0>),\n",
       " StructuredTool(name='add', description='Add two numbers.', args_schema=<class 'pydantic.v1.main.addSchema'>, func=<function add at 0x000002726208FBA0>)]"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {},
   "outputs": [],
   "source": [
    "openai_tools = [convert_to_openai_tool(tool) for tool in tools]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'type': 'function',\n",
       "  'function': {'name': 'multiply',\n",
       "   'description': 'Multiply two numbers together.',\n",
       "   'parameters': {'type': 'object',\n",
       "    'properties': {'x': {'type': 'number'}, 'y': {'type': 'number'}},\n",
       "    'required': ['x', 'y']}}},\n",
       " {'type': 'function',\n",
       "  'function': {'name': 'add',\n",
       "   'description': 'Add two numbers.',\n",
       "   'parameters': {'type': 'object',\n",
       "    'properties': {'x': {'type': 'integer'}, 'y': {'type': 'integer'}},\n",
       "    'required': ['x', 'y']}}},\n",
       " {'type': 'function',\n",
       "  'function': {'name': 'count_emails',\n",
       "   'description': 'Multiply two integers together.',\n",
       "   'parameters': {'type': 'object',\n",
       "    'properties': {'last_n_days': {'type': 'integer'}},\n",
       "    'required': ['last_n_days']}}},\n",
       " {'type': 'function',\n",
       "  'function': {'name': 'send_email',\n",
       "   'description': 'Add two integers.',\n",
       "   'parameters': {'type': 'object',\n",
       "    'properties': {'message': {'type': 'string'},\n",
       "     'recipient': {'type': 'string'}},\n",
       "    'required': ['message', 'recipient']}}}]"
      ]
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "openai_tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "llm_with_tools  = tongyi_llm.bind_tools(openai_tools)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "RunnableBinding(bound=ChatTongyi(client=<class 'dashscope.aigc.generation.Generation'>, dashscope_api_key=SecretStr('**********')), kwargs={'tools': [{'type': 'function', 'function': {'name': 'multiply', 'description': 'Multiply two numbers together.', 'parameters': {'type': 'object', 'properties': {'x': {'type': 'number'}, 'y': {'type': 'number'}}, 'required': ['x', 'y']}}}, {'type': 'function', 'function': {'name': 'add', 'description': 'Add two numbers.', 'parameters': {'type': 'object', 'properties': {'x': {'type': 'integer'}, 'y': {'type': 'integer'}}, 'required': ['x', 'y']}}}]})"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "llm_with_tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "msg = llm_with_tools.invoke(\"三加5是多少？\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "AIMessage(content='', additional_kwargs={'tool_calls': [{'function': {'name': 'add', 'arguments': '{\"x\": 3, \"y\": 5}'}, 'id': '', 'type': 'function'}]}, response_metadata={'model_name': 'qwen-turbo', 'finish_reason': 'tool_calls', 'request_id': '182839d7-1238-92cc-925c-aff2c42be94c', 'token_usage': {'input_tokens': 249, 'output_tokens': 22, 'total_tokens': 271}}, id='run-8a92afc0-db75-4f21-bcb4-d9148344930c-0', tool_calls=[{'name': 'add', 'args': {'x': 3, 'y': 5}, 'id': ''}])"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "msg"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "import json\n",
    "\n",
    "\n",
    "arguments=json.loads(msg.additional_kwargs['tool_calls'][0]['function']['arguments'])\n",
    "name=msg.additional_kwargs['tool_calls'][0]['function']['name']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'x': 3, 'y': 5}"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "arguments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'add'"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import Dict, List\n",
    "from langchain_core.messages import AIMessage\n",
    "def call_tools(msg: AIMessage) -> List[Dict]:\n",
    "    \"\"\"Simple sequential tool calling helper.\"\"\"\n",
    "    tool_map = {tool.name: tool for tool in tools}\n",
    "    tool_calls = msg.tool_calls.copy()\n",
    "    for tool_call in tool_calls:\n",
    "        tool_call[\"output\"] = tool_map[tool_call[\"name\"]].invoke(tool_call[\"args\"])\n",
    "    return tool_calls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [],
   "source": [
    "chain = llm_with_tools | call_tools"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[{'name': 'count_emails', 'args': {'last_n_days': 5}, 'id': '', 'output': 10}]"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#chain.invoke(\"三加五是多少?\")\n",
    "chain.invoke(\"我在过去 5 天内收到了多少封电子邮件?\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
